package joe;

import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

public class SceneModel<M extends Render.Model> extends SceneNode {
	public @Nullable M model;

	public SceneModel(@Nullable String name) {
		super(name);
	}

	@Override
	protected void onRender(@NotNull Render render) {
		var m = model;
		if (m != null) {
			var c = Engine.current().getCurCamera();
			if (c != null) {
				var mvp = m.getMVP();
				if (mvp != null)
					mvp.mul(getModelMat(), c.getViewProjMat());
				render.draw(m);
			}
		}
		super.onRender(render);
	}

	public static @NotNull Render.Mesh createQuadMesh() {
		return createQuadMesh(-0.5f, 0.5f, -0.5f, 0.5f);
	}

	// vertex-coord + tex-coord. vx:[x0,x1]; vy:[y1,y0]; tx/ty:[0,1]
	public static @NotNull Render.Mesh createQuadMesh(float x0, float x1, float y0, float y1) {
		var engine = Engine.current();
		var tmpPtr = engine.getTmpBuf().ptr();
		//@formatter:off
		UnsafeUtil.putFloat(tmpPtr +  4, x0, y1); UnsafeUtil.putInt(tmpPtr + 12, 0x0000_0000); // left-top     y1A
		UnsafeUtil.putFloat(tmpPtr + 16, x0, y0); UnsafeUtil.putInt(tmpPtr + 24, 0x0001_0000); // left-bottom    |
		UnsafeUtil.putFloat(tmpPtr + 28, x1, y1); UnsafeUtil.putInt(tmpPtr + 36, 0x0000_0001); // right-top    y0+--->
		UnsafeUtil.putFloat(tmpPtr + 40, x1, y0); UnsafeUtil.putInt(tmpPtr + 48, 0x0001_0001); // right-bottom  x0  x1
		//@formatter:on
		var render = engine.getRender();
		return render.createMesh(Render.TRIANGLE_STRIP, render.createVertexBuffer("f2us2", 12, tmpPtr + 4, 12 * 4));
	}

	public static @NotNull Render.Mesh createBoxMesh() {
		return createBoxMesh(-0.5f, 0.5f, -0.5f, 0.5f, -0.5f, 0.5f);
	}

	// only vertex-coord, no tex-coord
	public static @NotNull Render.Mesh createBoxMesh(float x0, float x1, float y0, float y1, float z0, float z1) {
		var engine = Engine.current();
		var tmpPtr = engine.getTmpBuf().ptr();
		//@formatter:off
		UnsafeUtil.putFloat(tmpPtr +  4, x0, y0, z0); //  left-bottom-near
		UnsafeUtil.putFloat(tmpPtr + 16, x1, y0, z0); // right-bottom-near  6----7
		UnsafeUtil.putFloat(tmpPtr + 28, x0, y1, z0); //  left-top-near    2----3|
		UnsafeUtil.putFloat(tmpPtr + 40, x1, y1, z0); // right-top-near    ||   ||
		UnsafeUtil.putFloat(tmpPtr + 52, x0, y0, z1); //  left-bottom-far  |4---|5
		UnsafeUtil.putFloat(tmpPtr + 64, x1, y0, z1); // right-bottom-far  0----1
		UnsafeUtil.putFloat(tmpPtr + 76, x0, y1, z1); //  left-top-far
		UnsafeUtil.putFloat(tmpPtr + 88, x1, y1, z1); // right-top-far
		//@formatter:on
		var render = engine.getRender();
		return render.createMesh(Render.TRIANGLES, render.createVertexBuffer("f3", 12, tmpPtr + 4, 12 * 8),
				engine.getBoxVertexIndex());
	}
}
